import详解

import:在当前模块中引入其他的语法单元(语法单元指:库/包/模块/函数/类,全局变量)

import系统:扩展命名空间及功能

  • import系统的构成:
    • import保留字:调用__import__()进行模块查找,以及模块的加载
    • __import__()函数:模块的查找,建立模块对象
    • importlib标准库:与import系统相关的丰富API
  • import的步骤:
    1. 模块的查找,找得到生成模块对象,找不到抛出ImportError
    2. 模块的加载,将模块对象加载到当前命名空间

import 系统是python代码复用和命名空间管理的精髓

模块的查找

拖过import保留字、__import__()、importlib标准库,获取输入参数:模块的名字。如pkg.pkg1.m1。按层次结构逐层查找。如pkg->pkg1->m1

查找路径:

  1. sys.modules:已被引入模块的字典,key是模块名/对象引用,value是模块对象 内含加载路径
  2. 用户通过import钩子扩展的查找模式:import hook
    • meta_path方式:将查找方法增加到sys.meta_path列表变量
    • import路径:将查找方法注册到sys.path_hooks列表变量
  3. 内置模块的路径
  4. sys.path(路径列表),里边元素可以是zip文件路径或URL

模块对象

万物皆对象,模块被导入后成为了模块对象,模块在程序中使用都是以对象形式体现。

模块的对象形式:模块在程序中使用都是以对象形式体现

类似类对象,模块对象在当前命名空间中只有一个。

建立模块对象的过程:找到模块后,如果模块对象存在,则使用现有模块对象;如果模块对象不存在,则创建一个新的模块对象,并将其加入sys.modules。最后在程序当前命名空间执行模块代码。

创建新的模块对象:importlib.abc.Loader.create_module()

执行创建的模块对象:importlib.abc.Loader.exec_module()

模块对象的命名空间:模块的命名空间与引用位置有直接关系。如果引用在文件顶层,则使用文件顶层命名空间访问模块;如果引用在非顶层,则使用局部命名空间访问模块

模块的加载

通过执行模块对象,就可以把文件对象加载到当前命名空,即模块的加载发生在importlib.abc.Loader.exec_module()调用期间。

import的使用方式

  1. import A 适合简单库名情况

    import A as a 适合复杂库名情况

    import A,B,C

    A,B,C 是 模块名,a 是一个别名/引用

    例如:

    import os

    import os, sys

    为当前命名空间生成一个子命名空间

  2. from A import B

    from A import B as b

    from A import B,C,D

from <模块名> import <函数名/类名/*>

将导入元素加载到当前命名空间下,加载成功后,产生类对象或函数对象,覆盖同名对象